package com.hansming.bss.modules.sfc.service;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hansming.bss.common.persistence.Page;
import com.hansming.bss.common.service.CrudService;
import com.hansming.bss.common.utils.IdGen;
import com.hansming.bss.common.utils.PropertiesLoader;
import com.hansming.bss.modules.gen.util.GenUtils;
import com.hansming.bss.modules.sfc.dao.CarDatePriceDao;
import com.hansming.bss.modules.sfc.dao.CarInfoDao;
import com.hansming.bss.modules.sfc.dao.CarServeDao;
import com.hansming.bss.modules.sfc.dao.ContactsDao;
import com.hansming.bss.modules.sfc.dao.CustomerDao;
import com.hansming.bss.modules.sfc.dao.CustomerScoreLogDao;
import com.hansming.bss.modules.sfc.dao.OrderDao;
import com.hansming.bss.modules.sfc.dao.OrderItemDao;
import com.hansming.bss.modules.sfc.dao.WxUserDao;
import com.hansming.bss.modules.sfc.entity.CarDatePrice;
import com.hansming.bss.modules.sfc.entity.CarInfo;
import com.hansming.bss.modules.sfc.entity.CarServe;
import com.hansming.bss.modules.sfc.entity.Contacts;
import com.hansming.bss.modules.sfc.entity.Customer;
import com.hansming.bss.modules.sfc.entity.CustomerScoreLog;
import com.hansming.bss.modules.sfc.entity.Line;
import com.hansming.bss.modules.sfc.entity.Order;
import com.hansming.bss.modules.sfc.entity.OrderItem;
import com.hansming.bss.modules.sfc.util.CarTimeHelp;
import com.hansming.bss.modules.sfc.util.PageBean;
import com.hansming.bss.modules.sfc.util.PhoneMsgUtil;
import com.hansming.bss.modules.sfc.util.SendMailUtil;
import com.hansming.bss.modules.sfc.util.TimeUtil;

/**
 * 订单Service
 * @author Hansming
 * @version 2017-09-19
 */
@Service
@Transactional(readOnly = true)
public class OrderService extends CrudService<OrderDao,Order>{
	
	@Autowired
	private OrderDao orderDao;
	
	@Autowired
	private CarDatePriceDao cardatepriceDao;
	
	@Autowired
	private CarInfoDao carinfoDao;
	
	@Autowired
	private CarServeDao carserveDao;
	
	@Autowired
	private ContactsDao contactsDao;
	
	@Autowired
	private	CustomerDao customerDao;
	
	@Autowired
	private OrderItemDao orderitemDao;
	
	@Autowired
	private CustomerScoreLogDao customerscorelogDao;
	
	@Autowired
	private	WxUserDao wxuserDAO;

	
	//房车订单详情页
	public Order getCarOrder(Order order){
		return orderDao.getCarOrder(order);
	}
	
	//线路订单详情页
	public Order getLineOrder(Order order){
		return orderDao.getLineOrder(order);
	}
	
	//操作后台获得房车订单
	public Page<Order> findCarPage(Page<Order> page, Order order){
		order.setPage(page);
		page.setList(orderDao.findCarList(order));
		return page;
	}
	
	//操作后台获得线路订单
	public Page<Order> findLinePage(Page<Order> page, Order order){
		order.setPage(page);
		page.setList(orderDao.findLineList(order));
		return page;
	}
	
	//跟人中心主页显示的最新的订单(num为显示的数量
	public List<Order> findOrderListByUserid(String uid,int num){
		return orderDao.findOrderListByUserid(uid,num);
	}
	
	//根据用户id查找其对应状态的订单 
		public List<Order> findOrderListBycusidAndOrderStats(String uid,String states){
			return orderDao.findOrderListBycusidAndOrderStats(uid, states);
		}

		
	//getsgin
		public Order getsgin(String orderid){
			return orderDao.getsgin(orderid);
		}
		
	//改变订单状态为待确认
		@Transactional(readOnly = false)
		public void changtotbd(String orderid){
			orderDao.changtotbd(orderid);
		}
		
		//改变订单状态为预定成功
		@Transactional(readOnly = false)
		public void changtosuccess(String orderid){
			orderDao.changtosuccess(orderid);
		}
		//改变订单状态为退款中
		@Transactional(readOnly = false)
		public void changtorefunding(String orderid){
			orderDao.changtorefunding(orderid);
		}
		//改变订单状态为已退款
		@Transactional(readOnly = false)
		public void changtorefunded(String orderid){
			orderDao.changtorefunded(orderid);
		}		

		
		public int findstateordernum(String uid,String states){
			return orderDao.findstateordernum(uid, states);
		}
		
		public List<Order> findOrderBytypeandstate(String type,String state,String uid){
			return orderDao.findOrderBytypeandstate(type, state, uid);
		}

		//全属性存储订单
		@Transactional(readOnly = false)
		public void savecarorder(String id,String num,String state,CarInfo carinfo ,String type,
				String came,String phone,String email,
				String identtype,String identnum,BigDecimal price,
				Customer user,String startDate,String endDate,
				int starttime,int endtime,Integer scorecosts,String cusmsg){
			orderDao.savecarorder(id, num, state, carinfo, type, came, phone, email, identtype, identnum, price, user, startDate, endDate, starttime, endtime, scorecosts,cusmsg);
		}
		
//		public void saveorder(Order order){
//			orderDao.saveorder(order);
//		}
		//储存线路的订单
		@Transactional(readOnly = false)
		public void savelineorder(Order order){
			orderDao.savelineorder(order);
		}
		
		@Transactional(readOnly = false)
		public void savecarorderbyorder(Order order){
			orderDao.savecarorderbyorder(order);
		}
		
		//支付订单prepayid存储
		@Transactional(readOnly = false)
		public void saveprepayid(String prepayid,String id){
			orderDao.saveprepayid(prepayid,id);
		}
		
		//支付根据prepayid修改状态为支付完成
		@Transactional(readOnly = false)
		public void updatestatebyprepayid(String prepayid){
		 orderDao.updatestatebyprepayid(prepayid);
		}
		
		@Transactional(readOnly = false)
		public void updatetextbywxnum(String wxnum){
			orderDao.updatetextbywxnum(wxnum);
		}
		
		public Order selectorederbywxnum(String wxnum){
			return orderDao.selectorederbywxnum(wxnum);
		}
		//根据order的id查找order
		
		public Order selectOrderByid(Order order){
			return orderDao.selectOrderByid(order);
		}
		
		//阿里支付根据订单id查找对应订单
		public Order alipayget(String id){
			
			return orderDao.alipayget(id);
		}
		
		/*
		 * 创建PC端用户订单
		 * 
		 */
		@Transactional(readOnly= false)
		public String  createPCUserOrder(HttpServletRequest request, HttpServletResponse response,String startDate,String endDate,int starttime,int endtime,String id,String serveid,String contactsid,String name,String identtype,String identnum,String email,String phone,String cusmsg,Integer score) throws Exception{
			int result = 1;    //返回关于结果的状态
			BigDecimal totleprice = new BigDecimal("0.00");		//准备计算总价格的基础
			SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
			Date now = new Date();
			CarInfo carinfo = carinfoDao.get(id);
			Date fdate = dft.parse(startDate);
			Calendar todatecal = Calendar.getInstance();
			todatecal.setTime(dft.parse(endDate));
			todatecal.set(Calendar.DATE, todatecal.get(Calendar.DATE)-1);
			Date tdate = dft.parse(dft.format(todatecal.getTime()));
			//若超过中午12点，则按照翌日的价格计算，起始的结束日期加1以下只为日期加1
			if(starttime >24)	{											
				Calendar fromcal = Calendar.getInstance();
				fromcal.setTime(dft.parse(startDate));
				fromcal.set(Calendar.DATE, fromcal.get(Calendar.DATE) + 1);
				fdate = dft.parse(dft.format(fromcal.getTime()));
				Calendar tocal = Calendar.getInstance();
				tocal.setTime(dft.parse(endDate));
				tocal.set(Calendar.DATE, tocal.get(Calendar.DATE));
				tdate = dft.parse(dft.format(tocal.getTime()));
			}	
			int hour = 0;										//多出整天数的时间，超过四小时算作一天，若不超过，按照比例每半小时为该天价格的1/16，单位为半小时
			int resulthour =endtime - starttime; 					//根据取车的时间 starttime 为 取车时间的id,id为0 = 00:00,id为1 = 00:30以此为例（tohour 同理)
			if(endtime == 0){
				Calendar tocal = Calendar.getInstance();
				tocal.setTime(tdate);
				tocal.set(Calendar.DATE, tocal.get(Calendar.DATE)-1);
				tdate = dft.parse(dft.format(tocal.getTime()));
			}
			BigDecimal extrPrice = new BigDecimal("0.00");				//超出整天数的小时所产生的额外价格
			if(resulthour >= 0 ){
				//超过一天的时间
				if(resulthour >8){
					Calendar tocal = Calendar.getInstance();			//days = days +1;
					tocal.setTime(tdate);
					tocal.set(Calendar.DATE, tocal.get(Calendar.DATE) + 1);
					tdate = dft.parse(dft.format(tocal.getTime()));
				}else{
					hour = resulthour;			//此为小时数为超过整天数4小时内，按每半小时当天单价的1/16计价
					//超出时间的价格计算，得出当日的价格/16*超出的时间
					CarDatePrice cardateprice = new CarDatePrice();
					cardateprice.setCarInfo(carinfo);
					cardateprice.setDatetime(dft.format(tdate));
					extrPrice = cardatepriceDao.getByDate(cardateprice.getCarInfo().getId(),cardateprice.getDatetime()).getPrice().divide(new BigDecimal("16")).multiply(new BigDecimal(String.valueOf(hour)));
					extrPrice = extrPrice.setScale(2,BigDecimal.ROUND_UP);
				}
			}else{
				if(resulthour < -40){
					hour = 48 + resulthour;
					CarDatePrice cardateprice = new CarDatePrice();
					cardateprice.setCarInfo(carinfo);
					cardateprice.setDatetime(dft.format(tdate));
					extrPrice = cardatepriceDao.getByDate(cardateprice.getCarInfo().getId(),cardateprice.getDatetime()).getPrice().divide(new BigDecimal("16")).multiply(new BigDecimal(String.valueOf(hour)));
					extrPrice = extrPrice.setScale(2,BigDecimal.ROUND_UP);
					Calendar tocal = Calendar.getInstance();
					tocal.setTime(tdate);
					tocal.set(Calendar.DATE, tocal.get(Calendar.DATE)-1);
					tdate = dft.parse(dft.format(tocal.getTime()));
				}
			}		
			//得到该计算日期的时间段的价格总价
			List<CarDatePrice>	carpirces = cardatepriceDao.getByDateFrom(dft.format(fdate),dft.format(tdate),carinfo);
			if(carpirces != null){
				for(CarDatePrice p:carpirces){
					totleprice = totleprice.add(p.getPrice());
				}
			}
			//加上额外的价格
			totleprice = totleprice.add(extrPrice);		
			
			//相差天数，不为自然天数
			int day = TimeUtil.Datecalc(startDate,endDate);
			//传过来的serveid以“|”分割开serveid
			String[] serves = serveid.split("\\|");
			BigDecimal price = new BigDecimal("0.00");//计算服务总价
			//此处先声明订单id
			Order order = new Order();
			order.setOrderNum();
			String orderid = IdGen.uuid();	
			order.setId(orderid);
			
			
			OrderItem orderitem = new OrderItem();
			orderitem.setId(IdGen.uuid());
			orderitem.setItemname("车辆租金");
			orderitem.setItemprice(totleprice);
			orderitem.setOrder(order);
			orderitemDao.insert(orderitem);
			
			String priceinfo = "车辆租金"+totleprice+"元  ";
			for(int i=0;i<serves.length;i++){
				if("7".equals(serves[i])){		//订单取消服务
					price = totleprice.multiply(new BigDecimal("0.04"));
					price = price.setScale(2,BigDecimal.ROUND_UP);
					totleprice = totleprice.add(price);
					OrderItem orderitem1 = new OrderItem();
					orderitem1.setId(IdGen.uuid());
					orderitem1.setItemname("订单取消服务");
					orderitem1.setItemprice(price);
					orderitem1.setOrder(order);
					orderitemDao.insert(orderitem1);
					priceinfo += "订单取消服务:"+price+"元  ";
				}
			}
			for(int i=0;i<serves.length;i++){
				if(serves[i] != null && serves[i] != ""){
					if("5".equals(serves[i])){				//司机代驾服务
						CarServe serve = carserveDao.get("5");				
						price = serve.getCaritemprice().multiply(new BigDecimal(String.valueOf(day)));
						price = price.setScale(2,BigDecimal.ROUND_UP);
						totleprice = totleprice.add(price);
						OrderItem orderitem2 = new OrderItem();
						orderitem2.setId(IdGen.uuid());
						orderitem2.setItemname("司机代驾服务");
						orderitem2.setItemprice(price);
						orderitem2.setOrder(order);
						orderitemDao.insert(orderitem2);
						priceinfo += "司机代驾服务:"+price+"元  ";
					}else if("6".equals(serves[i])){		//不计免赔服务
						CarServe serve = carserveDao.get("6");				
						price = serve.getCaritemprice().multiply(new BigDecimal(String.valueOf(day+1)));
						price = price.setScale(2,BigDecimal.ROUND_UP);
						totleprice = totleprice.add(price);
						OrderItem orderitem3 = new OrderItem();
						orderitem3.setId(IdGen.uuid());
						orderitem3.setItemname("不计免赔险");
						orderitem3.setItemprice(price);
						orderitem3.setOrder(order);
						orderitemDao.insert(orderitem3);
						priceinfo += "不计免赔险:"+price+"元  ";
					}else if("8".equals(serves[i])){
						CarServe serve = carserveDao.get("8");				//承租人责任险
						price = serve.getCaritemprice().multiply(new BigDecimal(String.valueOf(day+1)));
						price = price.setScale(2,BigDecimal.ROUND_UP);
						totleprice = totleprice.add(price);
						
						OrderItem orderitem4 = new OrderItem();
						orderitem4.setId(IdGen.uuid());
						orderitem4.setItemname("承租人责任险");
						orderitem4.setItemprice(price);
						orderitem4.setOrder(order);
						orderitemDao.insert(orderitem4);
						priceinfo += "承租人责任险:"+price+"元  ";
					}
				}		
			}
			
			
				//创建订单
			
			
		HttpSession session = request.getSession();
		String token = (String)session.getAttribute("token");
		
		Customer user = customerDao.selectbypcusertoken(token);
//			Customer user = customerDao.get("d69b39013b754b848f56ef8d49b5af4e");
			//计算订单积分
			if(score ==null){
				score = 0;
			}
			System.out.println(user);
					if(score <= user.getScore() && score > 0){
						if(score<100000){
							if(score/100<totleprice.intValue() ){//使用积分抵扣的钱小于总价
								BigDecimal bscore = new BigDecimal(score);					
								BigDecimal dscore =bscore.divide(new BigDecimal(100),2,RoundingMode.HALF_UP) ;
								totleprice = totleprice.subtract(dscore);
								
								//添加服务项
								OrderItem orderitem5 = new OrderItem();
								orderitem5.setId(IdGen.uuid());
								orderitem5.setItemname("积分抵扣");
								orderitem5.setItemprice(dscore);
								orderitem5.setOrder(order);
								orderitemDao.insert(orderitem5);
								//增加积分使用日志
								CustomerScoreLog csl = new CustomerScoreLog();
								csl.setId(IdGen.uuid());
								csl.setDatetime(dft.format(now));
								csl.setScore(score);
								csl.setDetail("订购"+carinfo.getTitle());
								csl.setType("2");
								csl.setCustomer(user);
								customerscorelogDao.insert(csl);
								//改变积分
								user.setScore(user.getScore()-score);
								customerDao.updatescore(user);
								priceinfo += "积分抵扣"+dscore+"元  ";
							}else{//使用积分抵扣的钱大于总价
								int costscore = totleprice.multiply(new BigDecimal("100.00")).intValue();
								BigDecimal money = new BigDecimal("1000.00");
								totleprice =  totleprice.subtract(money);	
								
								OrderItem orderitem5 = new OrderItem();
								orderitem5.setId(IdGen.uuid());
								orderitem5.setItemname("积分抵扣");
								orderitem5.setItemprice(totleprice);
								orderitem5.setOrder(order);
								orderitemDao.insert(orderitem5);
								
								CustomerScoreLog csl = new CustomerScoreLog();
								csl.setId(IdGen.uuid());
								csl.setDatetime(dft.format(now));
								csl.setScore(costscore);
								csl.setDetail("订购"+carinfo.getTitle());
								csl.setType("2");
								csl.setCustomer(user);
								customerscorelogDao.insert(csl);
								user.setScore(user.getScore()-costscore);
								customerDao.updatescore(user);
								priceinfo += "积分抵扣"+money+"元  ";
							}
						}else{
							if(1000 < totleprice.intValue()){
								BigDecimal dscore = new BigDecimal("1000.00");
								totleprice = totleprice.subtract(dscore);
								
								OrderItem orderitem5 = new OrderItem();
								orderitem5.setId(IdGen.uuid());
								orderitem5.setItemname("积分抵扣");
								orderitem5.setItemprice(dscore);
								orderitem5.setOrder(order);
								orderitemDao.insert(orderitem5);
								CustomerScoreLog csl = new CustomerScoreLog();	
								csl.setId(IdGen.uuid());
								csl.setDatetime(dft.format(now));
								csl.setScore(100000);
								csl.setDetail("订购"+carinfo.getTitle());
								csl.setType("2");
								csl.setCustomer(user);
								customerscorelogDao.insert(csl);
								user.setScore(user.getScore()-100000);
								customerDao.updatescore(user);
								priceinfo += "积分抵扣"+dscore+"元  ";
							}else{
								int costscore = totleprice.multiply(new BigDecimal("100.00")).intValue();
														
								OrderItem orderitem5 = new OrderItem();
								orderitem5.setId(IdGen.uuid());
								orderitem5.setItemname("积分抵扣");
								orderitem5.setItemprice(totleprice);
								orderitem5.setOrder(order);
								orderitemDao.insert(orderitem5);
								
									
								
								CustomerScoreLog csl = new CustomerScoreLog();
								csl.setId(IdGen.uuid());
								csl.setDatetime(dft.format(now));
								csl.setScore(costscore);
								csl.setDetail("订购"+carinfo.getTitle());
								csl.setType("2");
								csl.setCustomer(user);
								customerscorelogDao.insert(csl);
								user.setScore(user.getScore()-costscore);
								customerDao.updatescore(user);
								priceinfo += "积分抵扣"+totleprice+"元 ";
								totleprice =  totleprice.subtract(totleprice);
							}
							
						}
					}
			//保存订单
			
			order.setCreateDate(now);
			order.setCarinfo(carinfo);
			order.setType("1");
			order.setState("1");
			order.setCname(name);
			order.setPhone(phone);
			order.setEmail(email);
			order.setIdenttype(identtype);
			order.setIdentnum(identnum);
			
			order.setCustomer(user);
			order.setBeginDate(startDate);
			order.setEndDate(endDate);
			order.setBegintime(starttime);
			order.setEndtime(endtime);
			order.setScore_costs(score);
			order.setCusmsg(cusmsg);
			order.setProductname(carinfo.getTitle());
//			orderDao.savecarorder(orderid,order.getNum(), "1",carinfo, "1", name, phone, email, identtype, identnum, totleprice, user, startDate, endDate, starttime, endtime, score,cusmsg);
			if(totleprice.compareTo(new BigDecimal("0.00"))<=0){
				totleprice = new BigDecimal("0.00");
				PhoneMsgUtil.sendSingleSms(order.getPhone(), order.getNum());
				order.setState("2");
			}
			order.setPrice(totleprice);
			//存储联系人
			Contacts contactss = contactsDao.getByidentnum(identnum,user.getId());
			Contacts contacts = new Contacts();
			if(contactsid != null && !"".equals(contactsid)){
				contacts.setId(contactsid);
			}else if(contactss != null){
				contacts.setId(contactss.getId());
			}
			contacts.setCname(name);
			contacts.setEmail(email);
			contacts.setIdenttype(identtype);
			contacts.setIdentnum(identnum);
			contacts.setPhone(phone);
			contacts.setCustomer(user);
			if(contactsid != null && !"".equals(contactsid)){
				contacts.setId(contactsid);
				contactsDao.update(contacts);
			}else{
				contacts.setId(IdGen.uuid());
				contactsDao.insert(contacts);
			}
			
			//发送邮件给运营人员
			PropertiesLoader config = new PropertiesLoader("config.properties");
			String yunyingemail = config.getProperty("yunyingemail");
			try {
				SimpleDateFormat  sdf =   new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss"); 
				String emailtile = "小程序顾客创建租车待支付订单";
				String content = "<p>时间："+sdf.format(now)+"</p>"+								
											"<p>订单号:"+order.getNum()+"</p>"+
											"<p>联系人名称:"+name+"</p>"+
											"<p>联系人手机:"+phone+"</p>"+
											"<p>联系人邮箱:"+email+"</p>"+
											"<p>车辆名称:"+carinfo.getTitle()+" "+carinfo.getCity()+"</p>"+
											"<p>取车:"+startDate+" "+CarTimeHelp.changetotime(starttime)+"  还车："+endDate+" "+CarTimeHelp.changetotime(endtime)+"</p>"+
											"<p>订单详情;</p>"+
											"<p>"+priceinfo+"</p>"+
											"<p>总价为:"+totleprice+"</p>"+
											"<p>用户留言:"+cusmsg+"</p>";
											
//				SendMailUtil.Sendmail(yunyingemail,emailtile , content);//发送邮件动作
			} catch (Exception e) {
				// TODO Auto-generated catch block
				System.out.println("发送邮件失败");
			}
			orderDao.savecarorderbyorder(order);
			return  orderid;
		}
		
		//根据展示状态来查询订单;
		public	List<Order>  selectOrderByShowState(String uid,String state){
			return orderDao.selectOrderByShowState(uid,state);
		}
		
		public List<Order> getsmOrderBysmt(String ordernum,String type,PageBean pagebean,String userid){
			return orderDao.getsmOrderBysmt(ordernum, type,userid, pagebean);
		}
		
		public List<Order> getsmOrderBysmt2(String ordernum,String type,PageBean pagebean,String[] ids){
			return orderDao.getsmOrderBysmt2(ordernum, type,ids, pagebean);
		}
		
		public int getsmOrdernumBysmt(String ordernum,String type,String userid){
			return orderDao.getsmOrdernumBysmt(ordernum, type,userid);
		}
		
		public int getsmOrdernumBysmt2(String ordernum,String type,String[] ids){
			return orderDao.getsmOrdernumBysmt2(ordernum, type,ids);
		}
}
